﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using Landscape.Business.Entities;
//using DCTM = Landscape.Business.Interface.Documentum;
using NHibernate.Criterion;
using System.IO;

namespace Landscape.Business.FNH.Activities
{
    public class EmergencyActivities : BusinessActivities
    {

        public EmergencyActivities()
            : base()
        { }

        public EmergencyActivities(ISession pSession)
            : base(pSession)
        { }
        
        public Entities.EmergencyIncident GetIncidentByCode(Guid pIncidentID)
        {
            return CurrentSession.Get<EmergencyIncident>(pIncidentID);
        }

        public Entities.Scribe GetScribeByCode(Guid pScribeID)
        {
            return CurrentSession.Get<Scribe>(pScribeID);
        }

        public Guid SaveIncident(EmergencyIncident pIncident)
        {
            this.SaveEntity<EmergencyIncident>(pIncident);
            var criteria = CurrentSession.CreateCriteria<EmergencyIncident>();
            var items = criteria.List<EmergencyIncident>().Where(exp => exp.Title == pIncident.Title);
            return criteria.List<EmergencyIncident>().Where(exp => exp.Title == pIncident.Title && exp.CreatedDate == pIncident.CreatedDate).Single().ID;
        }

        public IEnumerable<EmergencyIncident> GetEmergencyIncidentsByTitle(string pTitle, int pPageNo, int pPageSize)
        {
            var criteria = CurrentSession.CreateCriteria<EmergencyIncident>();
            if (pTitle != null && pTitle.Trim() != string.Empty)
                criteria.Add(Expression.InsensitiveLike("Title", pTitle));

            criteria.Add(Expression.Eq("IsDeleted", false));

            criteria.AddOrder(new Order("CreatedDate", true));

            if (pPageSize == -1)
            {
                return criteria.List<EmergencyIncident>();
            }
            else
            {
                return criteria.List<EmergencyIncident>().Skip(pPageNo * pPageSize).Take(pPageSize).ToList();
            }
        }
        
        public StatusBoardEntry GetStatusBoardEntryByCode(Guid pEntryCode)
        {
            return CurrentSession.Get<StatusBoardEntry>(pEntryCode);
        }

        public StatusBoardItem GetStatusItemByCode(Guid pStatusItemCode)
        {
            return CurrentSession.Get<StatusBoardItem>(pStatusItemCode);
        }

        public IEnumerable<StatusBoardItem> GetStatusBoardItemsByTitle(string pTitle, int pPageNo, int pPageSize)
        {
            var criteria = CurrentSession.CreateCriteria<StatusBoardItem>();
            if (pTitle != null && pTitle.Trim() != string.Empty)
                criteria.Add(Expression.InsensitiveLike("Title", pTitle));

            criteria.Add(Expression.Eq("IsDeleted", false));

            criteria.AddOrder(new Order("Sequence", true));

            if (pPageSize == -1)
            {
                return criteria.List<StatusBoardItem>();
            }
            else
            {
                return criteria.List<StatusBoardItem>().Skip(pPageNo * pPageSize).Take(pPageSize).ToList();
            }
        }

        public void SaveStatusUpdate(Guid pStatusItemCode, Guid pIncidentCode, string pMessage, Guid pUserCode)
        {
            var incident = this.GetIncidentByCode(pIncidentCode);
            StatusBoardEntry entry = new StatusBoardEntry();
            entry.StatusEntry = pMessage;
            entry.StatusItem = this.GetStatusItemByCode(pStatusItemCode);
            entry.CreatedBy = pUserCode;
            entry.CreatedDate = DateTime.Now;

            incident.StatusBoardLog.Add(entry);

            this.SaveEntity<EmergencyIncident>(incident);
        }       

        public void SaveFile(Guid pIncID, string pFilePath, string pTitle, string pDescription, long pFileSize, Guid pUploadedBy)
        {
            //var inc = this.GetIncidentByCode(pIncID);

            //FileAttachment fa = new FileAttachment();
            //fa.Description = pDescription;
            //fa.FileName = new FileInfo(pFilePath).Name;
            //fa.FileSize = new FileInfo(pFilePath).Length;
            //fa.UploadBy = pUploadedBy;
            //fa.UploadDate = DateTime.Now;
            //fa.Title = pTitle;
            //fa.Description = pDescription;

            //var incFldrCreated = false;
            //var incFldrCode = string.Empty;

            //var sm = DCTM.SessionManager.GetManager();
            //var token = sm.CreateTPOTAdminSession();
            //if (token.LandingFolder.Folders.Count > 0)
            //{
            //    if (token.LandingFolder.Folders.Where(exp => exp.Name == "ERM").Count() > 0)
            //    {
            //        var ermFldr = token.LandingFolder.Folders.Where(exp => exp.Name == "ERM").Single();
            //        DCTM.Folder incFldr = null;

            //        if (ermFldr.Folders.Where(exp => exp.Name == pIncID.ToString()).Count() > 0)
            //        {
            //            incFldr = ermFldr.Folders.Where(exp => exp.Name == pIncID.ToString()).Single();
            //        }
            //        else
            //        {
            //            ermFldr.CreateFolder(pIncID.ToString());
            //            ermFldr.Refresh();
            //            incFldr = ermFldr.Folders.Where(exp => exp.Name == pIncID.ToString()).Single();
            //            incFldrCreated = true;
            //            incFldrCode = incFldr.DctmID;
            //        }

            //        DCTM.Document ermDoc = new DCTM.Document(token);

            //        fa.RepositoryCode = incFldr.UploadDocument(ermDoc, pFilePath).DctmCode;
            //    }
            //}

            //if (incFldrCreated)
            //{
            //    var incident = this.GetIncidentByCode(pIncID);
            //    incident.DctmFolderCode = incFldrCode;

            //    this.SaveIncident(incident);
            //}

            //inc.Attachments.Add(fa);
            //this.SaveIncident(inc);

            //this.SaveEntity<FileAttachment>(fa);
        }

        public EmergencyFeedback GetEmergencyFeedbackByID(Guid pFeedID)
        {
            return CurrentSession.Get<EmergencyFeedback>(pFeedID);
        }

        public Guid SaveFeedback(Guid pIncCode, EmergencyFeedback pFeedback)
        {
            var incident = this.GetIncidentByCode(pIncCode);
            incident.Feedback.Add(pFeedback);

            this.SaveIncident(incident);

            var criteria = CurrentSession.CreateCriteria<EmergencyFeedback>();
            return criteria.List<EmergencyFeedback>().Where(exp => exp.Comments == pFeedback.Comments && exp.CreatedBy == pFeedback.CreatedBy && exp.CreatedDate == pFeedback.CreatedDate).Single().ID;
        }

        public void SubmitFeedbackAndClose(Guid pIncCode, Guid pUserCode)
        {
            var incident = this.GetIncidentByCode(pIncCode);
            if (incident.Feedback != null && incident.Feedback.Count > 0)
            {
                foreach (var fb in incident.Feedback)
                {
                    fb.Status = FeedbackStatus.CLOSED;
                    fb.UpdatedBy = pUserCode;
                    fb.UpdatedDate = DateTime.Now;

                    if (fb.Type == FeedbackType.CORRECTIVE_ACTION)
                    {
                        if (fb.CorrectiveAction.Trim() != string.Empty && fb.AssignedTo != null && fb.ResponseDueDate.HasValue)
                        {
                            fb.CorrectiveActionInstance = new Entities.Action();
                            fb.CorrectiveActionInstance.Responder = fb.AssignedTo;
                            fb.CorrectiveActionInstance.CreatedBy = pUserCode;
                            fb.CorrectiveActionInstance.CreatedDate = DateTime.Now;
                            fb.CorrectiveActionInstance.Description = fb.CorrectiveAction;
                            fb.CorrectiveActionInstance.IsDeleted = false;
                            fb.CorrectiveActionInstance.ResponseDueDate = fb.ResponseDueDate;
                            fb.CorrectiveActionInstance.Reviewers.Add(fb.ReviewTo);
                            fb.CorrectiveActionInstance.Status = ActionStatus.NEW;
                            fb.CorrectiveActionInstance.Source = ActionSource.EM;
                            fb.CorrectiveActionInstance.UpdatedBy = pUserCode;
                            fb.CorrectiveActionInstance.UpdatedDate = DateTime.Now;
                            fb.CorrectiveActionInstance.Priority = ActionPriority.HIGH;
                            fb.CorrectiveActionInstance.Title = "[ER]-Title #" + incident.Title;
                            fb.CorrectiveActionInstance.ActionType = ActionType.CORRECTIVE;
                            fb.CorrectiveActionInstance.Vessel = incident.Vessel;
                        }
                        else
                        {
                            throw new Exception("At lease one of the corrective actions is missing any of approve, reviewer, corrective action description and/or expected date.");
                        }
                    }                    
                }

                incident.UpdatedBy = pUserCode;
                incident.UpdatedDate = DateTime.Now;
                incident.IsClosed = true;
                incident.CloseComment = "NONE";
                incident.ClosedBy = pUserCode;
                incident.ClosedDate = DateTime.Now;

                this.SaveIncident(incident);
            }
        }

        public ChatItem GetChatItemByID(Guid pChatID)
        {
            return CurrentSession.Get<ChatItem>(pChatID);
        }

        public Guid SaveChatItem(ChatItem pChatItem)
        {
            this.SaveEntity<ChatItem>(pChatItem);
            var criteria = CurrentSession.CreateCriteria<ChatItem>();
            var items = criteria.List<ChatItem>().Where(exp => exp.CreatedBy == pChatItem.CreatedBy && exp.CreatedDate == pChatItem.CreatedDate);
            return criteria.List<ChatItem>().Where(exp => exp.Message == pChatItem.Message).Single().ID;
        }        
    }
}
